﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSNN
{
    /// <summary>
    /// Нейронный слой
    /// </summary>
    public class NeuralLayer
    {
        /// <summary>
        /// Количество нейроннов в слое
        /// </summary>
        public int NeuronsCount { get; private set; }

        /// <summary>
        /// Массив нейроннов слоя
        /// </summary>
        public Neuron[] Neurons;

        /// <summary>
        /// Размерность нейронов данного слоя
        /// </summary>
        public int NeuronsDemension { get; private set; }

        /// <summary>
        /// Выходящий образ слоя
        /// </summary>
        private Image OutputImage;

        public NeuralLayer(int NeuronsCount, int NeuronsDemension)
        {
            this.NeuronsCount = 0;
            this.Neurons = null;
            this.NeuronsDemension = 0;
            this.OutputImage = new Image();
            this.OutputImage.SetImage(NeuronsCount);

            this.NeuronsCount = NeuronsCount;
            this.Neurons = new Neuron[NeuronsCount];
            this.NeuronsDemension = NeuronsDemension;

            // Установка нейронов
            for (int i = 0; i < NeuronsCount; i++)
            {
                this.Neurons[i] = new Neuron(NeuronsDemension);
                this.Neurons[i].SetNullWeight();
            }
        }

        /// <summary>
        /// Получение выходного образа данного слоя
        /// </summary>
        /// <param name="InputImage">Входной образ</param>
        /// <returns>Выходной образ</returns>
        public Image GetOutImage(Image InputImage)
        {
            if (InputImage == null)
            {
                throw new ArgumentNullException("Ошибка! Образ не определен.");
            }

            if (InputImage.InSignalsCount != this.NeuronsDemension)
            {
                throw new ArgumentException("Ошибка! Не соответсвующая размерность образа к данному нейронному слою.");
            }

            this.OutputImage.SetImage(this.NeuronsCount);

            for (int i = 0; i < OutputImage.InSignalsCount; i++)
            {
                this.OutputImage.InputSignals[i] = Neurons[i].GetOutSignal(InputImage);
            }

            return this.OutputImage;
        }

        /// <summary>
        /// Корректировка весового коэффициэнта нейрона в слое
        /// </summary>
        /// <param name="NumOfNeuron">Номер нейрона</param>
        /// <param name="NumOfWeight">Индекс веса</param>
        /// <param name="NewWeightValue">Новое значение веса</param>
        public void WeightCorrection(int NumOfNeuron, int NumOfWeight, double NewWeightValue)
        {
            this.Neurons[NumOfNeuron].WeightCorrection(NumOfWeight, NewWeightValue);
        }
        
    }
}
